﻿/**
 * XYGraph
 *
 * @author		Allen Chou
 * @version		1.0.0 (last update: Mar 29 2009)
 * @link        http://cjcat.blogspot.com
 * @link		http://cjcat2266.deviantart.com
 */

package idv.cjcat.display.graphs {
	import flash.display.*;
	import flash.events.*;
	
	import idv.cjcat.display.*;
	import idv.cjcat.display.graphs.*;
	
	public class XYGraph extends Sprite implements IValuePairGraph {
		
		private var _data:Vector.<ValuePair> = new Vector.<ValuePair>();
		public function get data():Vector.<ValuePair> { return _data; }
		
		public var minX:Number;
		public var maxX:Number;
		public var minY:Number;
		public var maxY:Number;
		
		/*
		public var axisX:Number = 0;
		public var axisY:Number = 0;
		public var axisLineStyleX:LineStyle;
		public var axisLineStyleY:LineStyle;
		*/
		
		private var _width:Number = 200;
		public override function get width():Number { return _width; }
		public override function set width(value:Number):void { _width = value; }
		
		private var _height:Number = 200;
		public override function get height():Number { return _height; }
		public override function set height(value:Number):void { _height = value; }
		
		public var graphLineStyle:LineStyle = new LineStyle();
		public var graphFill:Fill = null;
		
		public function XYGraph(minX:Number = 0, maxX:Number = 100, minY:Number = 0, maxY:Number = 100, data:Vector.<ValuePair> = null):void {
			this.minX = minX;
			this.maxX = maxX;
			this.minY = minY;
			this.maxY = maxY;
			if (data != null) _data = data;
		}
		
		public function add(valueX:Number, valueY:Number):void {
			_data.push(new ValuePair(valueX, valueY));
		}
		
		public function clear():Vector.<ValuePair> {
			var temp:Vector.<ValuePair> = _data;
			_data = new Vector.<ValuePair>();
			return temp;
		}
		
		public function setData(data:*):Vector.<ValuePair> {
			var temp:Vector.<ValuePair> = _data;
			_data = Vector.<ValuePair>(data).concat();
			return temp;
		}
		
		public function setDataByPairArray(data:*):Vector.<ValuePair> {
			var length:int = int(data.length / 2);
			var temp:Vector.<ValuePair> = _data;
			
			_data = new Vector.<ValuePair>();
			for (var i:int = 0; i < length; i++) {
				add(data[2 * i], data[2 * i + 1]);
			}
			
			return temp;
		}
		
		public function setDataByXYArrays(arrayX:*, arrayY:*):Vector.<ValuePair> {
			var temp:Vector.<ValuePair> = _data;
			var minLength:int = int(Math.min(arrayX.length, arrayY.length));
			
			_data = new Vector.<ValuePair>();
			for (var i:int = 0; i < minLength; i++) {
				add(arrayX[i], arrayY[i]);
			}
			
			return temp;
		}
		
		private var vp:ValuePair;
		private var w:Number, h:Number;
		private var useLineStyle:Boolean;
		private var useFill:Boolean;
		public function render(e:Event = null):void {
			graphics.clear();
			if (_data.length == 0) return;
			
			_data.sort(vpSort);
			
			useLineStyle = false;
			useFill = false;
			//set styles
			if (graphLineStyle != null) {
				if (graphLineStyle.alpha != 0) useLineStyle = true;
			}
			if (graphFill != null) {
				if (graphFill.alpha != 0) useFill = true;
			}
			if (useLineStyle) CJDisplay.lineStyle(this, graphLineStyle);
			if (useFill) CJDisplay.beginFill(this, graphFill);
			
			//start drawing
			w = maxX - minX;
			h = maxY - minY;
			
			if (useFill) graphics.moveTo(_data[0].value1 / w * _width, _height);
			else graphics.moveTo(_data[0].value1 / w * _width, _height - (_data[0].value2 / h * _height));
			for each (vp in _data) {
				graphics.lineTo(vp.value1 / w * _width, _height - (vp.value2 / h * _height));
			}
			if (useFill) {
				graphics.lineTo(vp.value1 / w * _width, _height);
				graphics.endFill();
			}
		}
		
		private static function vpSort(vp1:ValuePair, vp2:ValuePair):Number {
			if (vp1.value1 < vp2.value1) return -1;
			else return 1;
		}
	}
}